package com.lingz.manager.modules.minio.Controller;

import com.lingz.manager.common.utils.CommonUtil;
import com.lingz.manager.common.utils.ResultUtil;
import com.lingz.manager.common.vo.Result;
import com.lingz.manager.modules.base.entity.FileBySys;
import com.lingz.manager.modules.base.service.FileService;
import com.lingz.manager.modules.minio.util.MinioUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.apache.tomcat.util.http.fileupload.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Date;

@Api(tags = "文件操作接口")
@RestController
@RequestMapping(value = "/EnjoyGIS/minio")
public class MinioFileController {

    @Autowired
    private MinioUtil minioUtil;

    @Autowired
    private FileService fileService;

    @ApiOperation("上传一个文件（普通文件）")
    @RequestMapping(value = "/uploadfile", method = RequestMethod.POST)

    //parameter uploadfile
    //parameter bucket
    //[arameter objectName
    public Result fileupload(@RequestParam MultipartFile uploadfile, @RequestParam String bucket,
                             @RequestParam(required = false) String objectName) throws Exception {
        minioUtil.createBucket(bucket);
        String url = "";
        if (StringUtils.isNotBlank(objectName)) {
            url = minioUtil.uploadFile(uploadfile.getInputStream(), bucket, objectName + "/" + uploadfile.getOriginalFilename());
        } else {
            url = minioUtil.uploadFile(uploadfile.getInputStream(), bucket, uploadfile.getOriginalFilename());
        }
        return new ResultUtil<>().setData(url);
    }

    /**
     * uploadfile   文件
     * bucket  桶 tsaoko
     * objectName  分文件夹  可为空
     * createBy   上传人
     * **/
    @ApiOperation("上传一个文件（草果特定文件）")
    @RequestMapping(value = "/fileuploadTsaoko", method = RequestMethod.POST)
    public Result<Object> fileuploadTsaoko(@RequestParam MultipartFile file, @RequestParam String bucket,
                             @RequestParam(required = false) String objectName,String createBy) throws Exception {
        minioUtil.createBucket(bucket);
        SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHhhss");
        String dateStr = format.format(new Date());
        String url = "";
        if (StringUtils.isNotBlank(objectName)) {
            url = minioUtil.uploadFile(file.getInputStream(), bucket, dateStr+"/"+objectName+"/"+ file.getOriginalFilename());
        } else {
            url = minioUtil.uploadFile(file.getInputStream(), bucket,dateStr+"/"+ file.getOriginalFilename());
        }
        String fKey = CommonUtil.renamePic(file.getOriginalFilename());
        FileBySys f = new FileBySys();
        // 保存数据信息至数据库
        f.setName(file.getOriginalFilename());
        f.setSize(file.getSize());
        f.setType(file.getContentType());
        f.setFKey(fKey);
        f.setUrl(url);

        if (StringUtils.isNotBlank(objectName)) {
            f.setLocationUrl(dateStr+"/"+objectName + "/" + file.getOriginalFilename());
        } else {
            f.setLocationUrl(dateStr+"/"+ file.getOriginalFilename());
        }

        f.setCreateBy(createBy);
        fileService.save(f);
        return new ResultUtil<>().setData(f);
    }

    public String uploadMinio(@RequestParam MultipartFile file,
                              @RequestParam(required = false) String objectName,String createBy,String fileName,String locationUrl) throws Exception {
        String bucket = "tsaoko";
        minioUtil.createBucket(bucket);
        SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd-HHmmss");
        String dateStr = format.format(new Date());
        String url = "";
        if (StringUtils.isNotBlank(objectName)) {
            url = minioUtil.uploadFile(file.getInputStream(), bucket, dateStr+"/"+objectName + "/" + file.getOriginalFilename());
        } else {
            url = minioUtil.uploadFile(file.getInputStream(), bucket,dateStr+"/"+ file.getOriginalFilename());
        }
        String fKey = CommonUtil.renamePic(file.getOriginalFilename());
        FileBySys f = new FileBySys();
        // 保存数据信息至数据库
        f.setName(fileName);
        f.setSize(file.getSize());
        f.setType(file.getContentType());
        f.setFKey(fKey);
        f.setUrl(url);
        f.setLocationUrl(locationUrl);
        f.setCreateBy(createBy);
        fileService.save(f);
        return f.getId();
    }

    @ApiOperation("列出所有的桶")
    @RequestMapping(value = "/listBuckets", method = RequestMethod.GET)
    public Result<Object> listBuckets() throws Exception {
        return new ResultUtil<>().setData(minioUtil.listBuckets());
    }

    @ApiOperation("递归列出一个桶中的所有文件和目录")
    @RequestMapping(value = "/listFiles", method = RequestMethod.GET)
    public Result<Object> listFiles(@RequestParam String bucket) throws Exception {
        return new ResultUtil<>().setData(minioUtil.listFiles(bucket));
    }

    @ApiOperation("下载一个文件")
    @RequestMapping(value = "/downloadFile", method = RequestMethod.GET)
    public void downloadFile(@RequestParam String bucket, @RequestParam String objectName,
                             HttpServletResponse response) throws Exception {
        InputStream stream = minioUtil.download(bucket, objectName);
        ServletOutputStream output = response.getOutputStream();
        response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(objectName.substring(objectName.lastIndexOf("/") + 1), "UTF-8"));
        response.setContentType("application/octet-stream");
        response.setCharacterEncoding("UTF-8");
        IOUtils.copy(stream, output);
    }
    /**
     * 获取minio文件的下载或者预览地址
     * 取决于调用本方法的方法中的PutObjectOptions对象有没有设置contentType
     *
     * @param bucketName: 桶名
     * @param objectName:   文件名
     * 注意：通过minioClient.presignedGetObject(bucketName, fileName)
     * 获取的链接是下载还是预览的区别是上传文件时是否有指定 ContentType属性
     * 添加了 putObjectOptions.setContentType(file.getContentType());获取的链接就是预览链接，Minio支持图片及pdf格式文件预览
     */
    @ApiOperation("获取minio文件的下载或者预览地址")
    @RequestMapping(value = "/previewFile", method = RequestMethod.GET)
    public Result getPreviewFileUrl(String bucketName, String objectName) {
        String url = null;
        try {
            url = minioUtil.getPresignedObjectUrl(bucketName, objectName,300);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return new ResultUtil<>().setData(url);
    }

    @ApiOperation("删除一个文件")
    @RequestMapping(value = "/deleteFile", method = RequestMethod.GET)
    public Result deleteFile(@RequestParam String bucket, @RequestParam String objectName) throws Exception {
        minioUtil.deleteObject(bucket, objectName);
        return new ResultUtil<>().setData("删除成功");
    }

    @ApiOperation("删除一个桶")
    @RequestMapping(value = "/deleteBucket", method = RequestMethod.GET)
    public Result deleteBucket(@RequestParam String bucket) throws Exception {
        minioUtil.deleteBucket(bucket);
        return new ResultUtil<>().setData("删除成功");
    }


    @ApiOperation("复制一个文件")
    @GetMapping("/copyObject")
    public Result copyObject(@RequestParam String sourceBucket, @RequestParam String sourceObject, @RequestParam String targetBucket, @RequestParam String targetObject) throws Exception {
        minioUtil.copyObject(sourceBucket, sourceObject, targetBucket, targetObject);
        return new ResultUtil<>().setData("复制成功");
    }

    @GetMapping("/getObjectInfo")
    @ApiOperation("获取文件信息")
    public Result<Object> getObjectInfo(@RequestParam String bucket, @RequestParam String objectName) throws Exception {

        return new ResultUtil<>().setData(minioUtil.getObjectInfo(bucket, objectName));
    }

    @GetMapping("/getPresignedObjectUrl")
    @ApiOperation("获取一个连接以供下载")
    public Result<Object> getPresignedObjectUrl(@RequestParam String bucket, @RequestParam String objectName, @RequestParam Integer expires) throws Exception {

        return new ResultUtil<>().setData(minioUtil.getPresignedObjectUrl(bucket, objectName, expires));
    }

    @GetMapping("/listAllFile")
    @ApiOperation("获取minio中所有的文件")
    public Result<Object> listAllFile() throws Exception {

        return new ResultUtil<>().setData(minioUtil.listAllFile());
    }


}
